Watching Files Programmatically

Now that you have a better handle on the use of various readers and writers, you’ll look at the role of the FileSystemWatcher class. This type can be quite helpful when you wish to monitor (or “watch”) files on your system programmatically. Specifically, you can instruct the FileSystemWatcher type to monitor files for any of the actions specified by the System.IO.NotifyFilters enumeration (many of these members are self-explanatory, but you should still check the .NET Framework 4.0 SDK documentation for more details):

public enum NotifyFilters
{
    Attributes, CreationTime,
    DirectoryName, FileName,
    LastAccess, LastWrite,
    Security, Size
}

To begin working with the FileSystemWatcher type, you need to set the Path property to specify the name (and location) of the directory that contains the files you want to monitor, as well as the Filter property that defines the file extensions of the files you want to monitor.

At this point, you may choose to handle the Changed, Created, and Deleted events, all of which work in conjunction with the FileSystemEventHandler delegate. This delegate can call any method matching the following pattern:

// The FileSystemEventHandler delegate must point
// to methods matching the following signature.
void MyNotificationHandler(object source, FileSystemEventArgs e)

You can also handle the Renamed event using the RenamedEventHandler delegate type, which can call methods that match the following signature:

// The RenamedEventHandler delegate must point
// to methods matching the following signature.
void MyRenamedHandler(object source, RenamedEventArgs e)

Next, let’s look at the process of watching a file. Assume you have created a new directory on your C: drive named MyFolder that contains various *.txt files (named whatever you wish). The following Console Application (named MyDirectoryWatcher) monitors the *.txt files in the MyFolder directory and prints out messages when files are created, deleted, modified, or renamed:

static void Main(string[] args)
{
    Console.WriteLine("***** The Amazing File Watcher App *****\n");

    // Establish the path to the directory to watch.
    FileSystemWatcher watcher = new FileSystemWatcher();
    try
    {
        watcher.Path = @"C:\MyFolder";
    }
    catch(ArgumentException ex)
    {
        Console.WriteLine(ex.Message);
        return;
    }

    // Set up the things to be on the lookout for.
    watcher.NotifyFilter = NotifyFilters.LastAccess
        | NotifyFilters.LastWrite
        | NotifyFilters.FileName
        | NotifyFilters.DirectoryName;
        
    // Only watch text files.
    watcher.Filter = "*.txt";

    // Add event handlers.
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    // Begin watching the directory.
    watcher.EnableRaisingEvents = true;
    
    // Wait for the user to quit the program.
    Console.WriteLine(@"Press 'q' to quit app.");
    while(Console.Read()!='q');
}

The two event handlers simply print out the current file modification:

static void OnChanged(object source, FileSystemEventArgs e)
{
    // Specify what is done when a file is changed, created, or deleted.
    Console.WriteLine("File: {0} {1}!", e.FullPath, e.ChangeType);
}

static void OnRenamed(object source, RenamedEventArgs e)
{
    // Specify what is done when a file is renamed.
    Console.WriteLine("File: {0} renamed to\n{1}", e.OldFullPath, e.FullPath);
}

To test this program, run the application and open Windows Explorer. Try renaming your files, creating a *.txt file, deleting a *.txt file, and so forth. You will see various bits of information generated about the state of the text files within your MyFolder, as in this example:

***** The Amazing File Watcher App *****

Press 'q' to quit app.
File: C:\MyFolder\New Text Document.txt Created!
File: C:\MyFolder\New Text Document.txt renamed to
C:\MyFolder\Hello.txt
File: C:\MyFolder\Hello.txt Changed!
File: C:\MyFolder\Hello.txt Changed!
File: C:\MyFolder\Hello.txt Deleted!

Source Code You can find the MyDirectoryWatcher application under the Chapter 20 subdirectory.

That wraps up this chapter’s look at fundamental IO operations within the .NET platform. While you will certainly use these techniques in many of your applications, you might also find that object serialization services can greatly simplify how you persist large amounts of data.